﻿using System;
using System.Collections.Generic;
using System.Text;

using ZoneFiveSoftware.Common.Data;
using ZoneFiveSoftware.Common.Data.Fitness;
using ZoneFiveSoftware.Common.Data.Measurement;

using ZoneFiveSoftware.Common.Visuals;
using ZoneFiveSoftware.Common.Visuals.Fitness;
using System.Runtime.InteropServices;

namespace PolarImport.DeviceImporter
{
    /// <summary>
    /// A class to calculate the memory usage of the
    /// connected device
    /// </summary>
    internal class PolarMemory
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="PolarMemory"/> class.
        /// </summary>
        /// <param name="psmi">The polar monitor information used during this 
        /// import session. <see cref="PolarImport.PolarSSetMonitorInfo"/>.</param>
        public PolarMemory(PolarSSetMonitorInfo psmi)
        {
            freeMem = psmi.iFreeMemoryInBytes;
            totalMem = psmi.iTotalMemoryInBytes;
        }

        public int FreeMem
        {
            get { return freeMem; }
        }
        public int TotalMem
        {
            get { return totalMem;}
        }
        public int UsedMem
        {
            get { return totalMem - freeMem; }
        }
        public float UsedMemPercentage
        { 
            get {return (float)UsedMem / (float)totalMem;}
        }

        private int freeMem;
        private int totalMem;
    }

    internal class PolarImportJobs
    {
        internal static bool ProcessSonicLinkData(DeviceConfigurationInfo configInfo,
                                             IJobMonitor monitor,
                                             IImportResults importResults,
                                             PolarSSetMonitorInfo psmi)
        {
            int FitnessFileCount = PolarHRM.GetFitnessFileCount();
#if (DEBUG)
            Plugin.AddDebugInfo(string.Format("{0} Fitness Files müssen bearbeitet werden:",FitnessFileCount ));      
#endif
            string MonitorName = PolarHRM.GetHRMonitorName(psmi.iMonitorInUse, psmi.iMonitorSubModel);
            if (FitnessFileCount > 0)
            {
                for (int FitnessFile = 0; FitnessFile < FitnessFileCount; FitnessFile++)
                {
                    monitor.StatusText = string.Format(Properties.Resources.PolarImport_Import_FitnessFileCount +
                        Environment.NewLine, FitnessFileCount) +
                        string.Format(Properties.Resources.PolarImport_Import_ProcessingFile, FitnessFile);
                    monitor.PercentComplete = (float)FitnessFile / (float)FitnessFileCount;

                    PolarHRM.AnalyzeFile(FitnessFile, 0);

                    // See, if the user records his hr as bpm or as %hrmax
                    float HRFactor = 1f;
                    if (PolarHRM.GetRecParam(RecData.REC_HR_LIMIT_VIEW) == 1)
                    {
                        HRFactor = (float)PolarHRM.GetRecParam(RecData.REC_USER_HR_MAX) / 100f;
                    }
                    // Look, what units the user uses on his watch
                    Length.Units distanceUnitRec = Length.Units.Kilometer;
                    Length.Units altitudeUnitRec = Length.Units.Meter;
                    Temperature.Units tempUnitRec = Temperature.Units.Celsius;
                    if (PolarHRM.GetRecParam(RecData.REC_EURO_US_UNITS) == 1)
                    {
                        distanceUnitRec = Length.Units.Mile;
                        altitudeUnitRec = Length.Units.Foot;
                        tempUnitRec = Temperature.Units.Fahrenheit;
                    }
#if (DEBUG)
                    Plugin.AddDebugInfo(string.Format("HRFactor = {0}", HRFactor));
                    Plugin.AddDebugInfo(string.Format("DistanceUnit = {0}", distanceUnitRec.ToString()));
                    Plugin.AddDebugInfo(string.Format("AltitudeUnit = {0}", altitudeUnitRec.ToString()));
                    Plugin.AddDebugInfo(string.Format("TemperatureUnit = {0}", tempUnitRec.ToString()));
#endif
                    DateTime startdate = PolarHRM.ConvertHRMDate(PolarHRM.GetRecParam(RecData.REC_START_DATE));
                    DateTime starttime = PolarHRM.ConvertHRMTime(PolarHRM.GetRecParam(RecData.REC_START_TIME));
                    DateTime startDateTime = new DateTime(startdate.Year, startdate.Month, startdate.Day, starttime.Hour, starttime.Minute, starttime.Second);
                    // Maybe it is not necessary to convert to UniversalTime. For me it works. The StartTime is correct. Without
                    // this the StartTime is 1 hour to much.
                    startDateTime = startDateTime.ToUniversalTime();

                    IActivity activity = importResults.AddActivity(startDateTime);
#if (DEBUG)
                    Plugin.AddDebugInfo(string.Format("FitnessFile #{0} erfolgreich angelegt.", FitnessFile));
#endif
                    if (configInfo.WriteBasicValues)
                    {
                        WriteBasicValues(MonitorName, HRFactor, distanceUnitRec, altitudeUnitRec, tempUnitRec, activity, configInfo );
                    }

                    // Process the laps
                    int totalLaps = PolarHRM.GetNbrOfIntTimes();
                    if (configInfo.WriteLapData && (totalLaps > 1))
                    {
#if (DEBUG)
                        activity.Notes += "-- LAP DATA --------------------------------------------------"+Environment.NewLine ;
#endif
                        double oldDistance = 0;
                        double actDistance = 0;
                        TimeSpan oldLapDuration = new TimeSpan(0, 0, 0);
                        TimeSpan actLapDuration = new TimeSpan(0, 0, 0);
                        TimeSpan fiveSeconds = new TimeSpan(0, 0, 5);
                        DateTime LapStartTime = startDateTime;
                        DateTime LapEndTime = DateTime.MinValue;
                        DateTime ActTime = DateTime.MinValue;
                        activity.CadencePerMinuteTrack = new NumericTimeDataSeries();
                        activity.HeartRatePerMinuteTrack = new NumericTimeDataSeries();
                        for (int LapNumber = 0; LapNumber < totalLaps; LapNumber++)
                        {
                            // Fill in data to distance track.
                            if (LapNumber == 0)
                            {
                                activity.DistanceMetersTrack = new DistanceDataTrack();
                                activity.DistanceMetersTrack.Add(startDateTime, 0f);
                            }

                            // Get Lap Duration and Lap Distance. (NOTE: These are cummulated values!)
                            actLapDuration = new TimeSpan(0, 0, PolarHRM.GetIntTimeData(LapNumber, LapData.INT_INT_TIME) / 10);
                            // Bug in polar docu, not meters/yards but meters/ 1/1000 miles 
                            actDistance = PolarHRM.GetIntTimeData(LapNumber, LapData.INT_LAP_DISTANCE) / 1000.0;
                            // now actDistance is in km or miles!
                            actDistance = Length.Convert(actDistance, distanceUnitRec, Length.Units.Meter);
                            // and now in m!
                            // add to distance track
                            activity.DistanceMetersTrack.Add(startDateTime + actLapDuration, (float)actDistance);
                            
                            // calculate the lap time and distance (NOTE: To get the per lap info!)
                            actLapDuration -= oldLapDuration;
                            oldLapDuration += actLapDuration;
                            actDistance -= oldDistance;
                            oldDistance += actDistance;

                            // Add one new Lap to the activity.
                            activity.Laps.Add(LapStartTime, actLapDuration);
#if (DEBUG)
                            Plugin.AddDebugInfo(string.Format("Lap {0} hinzugefügt:", LapNumber +1));
                            Plugin.AddDebugInfo(string.Format(" - Startzeit = {0}", LapStartTime.ToShortTimeString()));
                            Plugin.AddDebugInfo(string.Format(" - Dauer = {0}s", actLapDuration));
                            Plugin.AddDebugInfo(string.Format(" - Distanz = {0}m", actDistance));
#endif
                            // Update this lap with the data from the HR Monitor.
                            ILapInfo LapInfo = activity.Laps[LapNumber];
                            LapInfo.TotalDistanceMeters = (float)actDistance;
                            LapInfo.AverageCadencePerMinute = PolarHRM.GetIntTimeData(LapNumber, LapData.INT_AVG_CADENCE);
                            LapInfo.AverageHeartRatePerMinute = PolarHRM.GetIntTimeData(LapNumber, LapData.INT_AVE_SAMPLE) * HRFactor;

                            // Add the average values as data tracks to the activity.
                            // => Fake "Time Based Values", five-seconds step...
                            LapEndTime = LapStartTime + actLapDuration;
                            ActTime = LapStartTime;
                            while (ActTime < LapEndTime)
                            {
                                activity.HeartRatePerMinuteTrack.Add(ActTime, LapInfo.AverageHeartRatePerMinute);
                                activity.CadencePerMinuteTrack.Add(ActTime, LapInfo.AverageCadencePerMinute);
                                ActTime += fiveSeconds;
                            }
                            activity.HeartRatePerMinuteTrack.Add(LapEndTime, LapInfo.AverageHeartRatePerMinute);
                            activity.CadencePerMinuteTrack.Add(LapEndTime, LapInfo.AverageCadencePerMinute);
#if (DEBUG)                 
                            // Add detailed infos about each lap to the notes field of ST.                         
                            activity.Notes += string.Format("Lap {0:d}:", LapNumber + 1) + Environment.NewLine;
                            foreach (LapData lapdata in Enum.GetValues(typeof(LapData)))
                            {
                                activity.Notes += lapdata.ToString() + " = " + PolarHRM.GetIntTimeData(LapNumber, lapdata).ToString() + Environment.NewLine;
                            }
#endif
                            LapStartTime += actLapDuration;
                        }
                    }
                    // Write IN-Zone times to the notes field
                    double inZoneTime = (double)PolarHRM.GetRecParam(RecData.REC_TARGETZONE_S_IN) / 10.0;
                    activity.Notes += Environment.NewLine;
                    activity.Notes += string.Format("IN-ZONE: {0:F2}sec", inZoneTime);
#if (DEBUG)
                     //enter all data in the notes field.
                    activity.Notes += "-- DETAILED REC DATA --------------------------------------------------" + Environment.NewLine;
                    foreach (RecData recdata in Enum.GetValues(typeof(RecData)))
                    {
                        activity.Notes += recdata.ToString() + " = " + PolarHRM.GetRecParam(recdata).ToString() + Environment.NewLine;
                    }
                    Plugin.AddDebugInfo("'Detailed Infos' erfolgreich geschrieben.");
#endif
                }
                return true;
            }
            monitor.ErrorText = Properties.Resources.PolarImport_Import_NoFitnessFileFound;
            return false;
        }


        /// <summary>
        /// Processing of the raw data read by Import function. Store processed data in corresponding
        /// SportTracks structures. This Polar S725X HRM supportes time based values. These are stored
        /// in the corresponding NumericTimeDataSeries.
        /// </summary>
        /// <param name="monitor">The active job monitor for this import. Shows progress of import.</param>
        /// <param name="importResults">The imported data. This data is processed by SportTrack safter successful import.</param>
        /// <returns>True, if data processing was successful.<br></br>False, if data processing fails.</returns>
        internal static bool ProcessSAXNData(DeviceConfigurationInfo configInfo, 
                                             IJobMonitor monitor, 
                                             IImportResults importResults, 
                                             PolarSSetMonitorInfo psmi)
        {
            PolarExerciseFile pef = new PolarExerciseFile();
            pef.iSize = Marshal.SizeOf(pef);
            string MonitorName = PolarHRM.GetHRMonitorName(psmi.iMonitorInUse, psmi.iMonitorSubModel);
            int TotalFiles = psmi.iTotalFiles;
#if (DEBUG)
            Plugin.AddDebugInfo(string.Format("{0} Dateien auf der Uhr", TotalFiles));
#endif
            string FirstStatus = MonitorName + Environment.NewLine +
                                 String.Format(Properties.Resources.PolarImport_Import_FitnessFileCount + Environment.NewLine, TotalFiles);
            monitor.StatusText = FirstStatus;

            for (int Exercise = 0; Exercise < TotalFiles; Exercise++)
            {

#if (DEBUG)
                Plugin.AddDebugInfo(string.Format("Datei {0} bearbeiten...", Exercise + 1));
#endif
                monitor.StatusText = string.Format(FirstStatus +
                        Properties.Resources.PolarImport_Import_ProcessingFile, null, Exercise);
                monitor.PercentComplete = ((float)Exercise + 1.0f) / (float)TotalFiles;

                if (!PolarHRM.GetExeFileInfo(Exercise, pef))
                {
#if (DEBUG)
                    Plugin.AddDebugInfo("ERROR: 'GetExeFileInfo' fehlgeschlagen!");
#endif
                    monitor.ErrorText = Properties.Resources.PolarImport_General_ReadingCancelled; // TODO: use resources string
                    return false;
                }

                if (!PolarHRM.AnalyzeFile(Exercise, 0))
                {
#if (DEBUG)
                    Plugin.AddDebugInfo("ERROR: 'AnalyzeFile' fehlgeschlagen!");
#endif
                    monitor.ErrorText = Properties.Resources.PolarImport_General_ReadingCancelled; // TODO: use resources string
                    return false;
                }

                // See, if the user records his hr as bpm or as %hrmax
                float HRFactor = 1f; // assume bpm
                if (PolarHRM.GetRecParam(RecData.REC_HR_LIMIT_VIEW) == 1)
                {
                    // if yes, then calculate the factor accordung to HRmax.
                    HRFactor = (float)PolarHRM.GetRecParam(RecData.REC_USER_HR_MAX) / 100f;
                }
                // Look, what units the user uses on his watch
                Length.Units distanceUnitRec = Length.Units.Kilometer;
                Length.Units altitudeUnitRec = Length.Units.Meter;
                Temperature.Units tempUnitRec = Temperature.Units.Celsius;
                if (PolarHRM.GetRecParam(RecData.REC_EURO_US_UNITS) == 1)
                {
                    distanceUnitRec = Length.Units.Mile;
                    altitudeUnitRec = Length.Units.Foot;
                    tempUnitRec = Temperature.Units.Fahrenheit;
                }
#if (DEBUG)
                Plugin.AddDebugInfo(string.Format("HRFactor = {0}", HRFactor));
                Plugin.AddDebugInfo(string.Format("DistanceUnit = {0}", distanceUnitRec.ToString()));
                Plugin.AddDebugInfo(string.Format("AltitudeUnit = {0}", altitudeUnitRec.ToString()));
                Plugin.AddDebugInfo(string.Format("TemperatureUnit = {0}", tempUnitRec.ToString()));
#endif

                DateTime startdate = PolarHRM.ConvertHRMDate(PolarHRM.GetRecParam(RecData.REC_START_DATE));
                DateTime starttime = PolarHRM.ConvertHRMTime(PolarHRM.GetRecParam(RecData.REC_START_TIME));
                DateTime startDateTime = new DateTime(startdate.Year, startdate.Month, startdate.Day, starttime.Hour, starttime.Minute, starttime.Second);
                // Maybe it is not necessary to convert to UniversalTime. For me it works. The StartTime is correct. Without
                // this the StartTime is 1 hour to much.
                startDateTime = startDateTime.ToUniversalTime();
#if (DEBUG)
                Plugin.AddDebugInfo(string.Format("Startzeit von Exercise {0}: {1}", Exercise + 1, startDateTime));
#endif
                IActivity activity = importResults.AddActivity(startDateTime);
                if (configInfo.WriteBasicValues)
                {
                    WriteBasicValues(MonitorName, HRFactor, distanceUnitRec, altitudeUnitRec, tempUnitRec, activity, configInfo );
                }

                #region Write timebased values

                if (configInfo.WriteTimeBasedValues)
                {
                    // Fill in Time based data
                    int SampleRate = pef.iSamplingRate;
                    int TotalSamples = PolarHRM.GetNbrOfHRMSamples();
                    activity.HeartRatePerMinuteTrack = new NumericTimeDataSeries();
                    float OldDistance = 0.0F;
                    float ActDistance = 0.0F;
                    for (int Sample = 0; Sample < TotalSamples; Sample++)
                    {
                        DateTime SampleTime = startDateTime + new TimeSpan(0, 0, Sample * SampleRate);
                        activity.HeartRatePerMinuteTrack.Add(SampleTime, PolarHRM.GetHRMSamples(SampleData.CC_HRATE, Sample) * HRFactor);
                        // Aus der aufgezeichneten Geschwindigkeitskurve die Entfernungskurve ausrechnen:
                        if (pef.bSpeed == true)
                        {
                            if (activity.DistanceMetersTrack == null)
                                activity.DistanceMetersTrack = new DistanceDataTrack();
                            
                            ActDistance = PolarHRM.GetHRMSamples(SampleData.CC_SPEED, Sample) / 10.0F * SampleRate / 3600.0F;
                            // In ActDistance stehen nun Kilometer oder Meilen, noch umrechnen:
                            ActDistance = (float)Length.Convert(ActDistance, distanceUnitRec, Length.Units.Meter);
                            activity.DistanceMetersTrack.Add(SampleTime, OldDistance + ActDistance);
                            OldDistance += ActDistance;
                        }
                        if (pef.bAltitude == true)
                        {
                            if (activity.ElevationMetersTrack == null)
                                activity.ElevationMetersTrack = new NumericTimeDataSeries();
                            float actAltiude = PolarHRM.GetHRMSamples(SampleData.CC_ALT, Sample);
                            // Höhe noch in Meter oder feet, Umrechnung:
                            actAltiude = (float)Length.Convert(actAltiude, altitudeUnitRec, Length.Units.Meter);
                            activity.ElevationMetersTrack.Add(SampleTime, actAltiude);
                        }
                        if (pef.bCadence == true)
                        {
                            if (activity.CadencePerMinuteTrack == null)
                                activity.CadencePerMinuteTrack = new NumericTimeDataSeries();
                            activity.CadencePerMinuteTrack.Add(SampleTime, PolarHRM.GetHRMSamples(SampleData.CC_CAD, Sample));
                        }
                        if (pef.bPower == true)
                        {
                            if (activity.PowerWattsTrack == null)
                                activity.PowerWattsTrack = new NumericTimeDataSeries();
                            activity.PowerWattsTrack.Add(SampleTime, PolarHRM.GetHRMSamples(SampleData.CC_POWER, Sample));
                        }
                    }
#if (DEBUG)
                    Plugin.AddDebugInfo("'Time Based Values' erfolgreich geschrieben.");
#endif
                }
                #endregion

                #region Write lap data

                if (configInfo.WriteLapData)
                {
                    // Process the laps
                    int totalLaps = PolarHRM.GetNbrOfIntTimes();
                    if (totalLaps > 1)
                    {
                        float oldDistance = 0f;
                        float actDistance = 0f;
                        double actDistanceRec = 0;
                        TimeSpan oldLapDuration = new TimeSpan(0, 0, 0);
                        TimeSpan actLapDuration = new TimeSpan(0, 0, 0);
                        DateTime LapStartTime = startDateTime;
                        DateTime LapEndTime = DateTime.MinValue;
                        DateTime ActTime = DateTime.MinValue;
                        for (int LapNumber = 0; LapNumber < totalLaps; LapNumber++)
                        {
                            // Get Lap Duration and Lap Distance. (NOTE: This are cummulated values!)
                            actLapDuration = new TimeSpan(0, 0, PolarHRM.GetIntTimeData(LapNumber, LapData.INT_INT_TIME) / 10);
            
                            actDistanceRec = PolarHRM.GetIntTimeData(LapNumber, LapData.INT_LAP_DISTANCE)/1000.0;
                            // Now actDistanceRec is in km or miles
                            actDistance = (float)Length.Convert(actDistanceRec, distanceUnitRec, Length.Units.Meter);
                            // And now in Meters

                            // calculate the lap time and distance (NOTE: To get the per lap info!)
                            actLapDuration -= oldLapDuration;
                            oldLapDuration += actLapDuration;
                            actDistance -= oldDistance;
                            oldDistance += actDistance;

                            // Add one new Lap to the activity.
                            activity.Laps.Add(LapStartTime, actLapDuration);

                            // Update this lap with the data from the HR monitor.
                            ILapInfo LapInfo = activity.Laps[LapNumber];
                            LapInfo.TotalDistanceMeters = actDistance;
                            LapInfo.AverageCadencePerMinute = PolarHRM.GetIntTimeData(LapNumber, LapData.INT_AVG_CADENCE);
                            LapInfo.AveragePowerWatts = PolarHRM.GetIntTimeData(LapNumber, LapData.INT_AVE_POWER);
                            LapInfo.AverageHeartRatePerMinute = PolarHRM.GetIntTimeData(LapNumber, LapData.INT_AVE_SAMPLE) * HRFactor;
#if (DEBUG)
                            //Add detailed Info to the notes field of ST:
                            activity.Notes += string.Format("Lap {0:d}:", LapNumber) + Environment.NewLine;
                            activity.Notes += LapInfo.StartTime.ToShortTimeString() + ": " + LapInfo.TotalTime.ToString() + Environment.NewLine;
                            activity.Notes += LapInfo.TotalDistanceMeters.ToString() + "m" + Environment.NewLine;
                            activity.Notes += LapInfo.AverageCadencePerMinute.ToString() + "rpm" + Environment.NewLine;
                            activity.Notes += LapInfo.AverageHeartRatePerMinute.ToString() + "bpm" + Environment.NewLine;
                            activity.Notes += "Polar Raw Lap Data:" + Environment.NewLine;
                            //Add the raw polar lap info to the notes field of ST:
                            foreach (LapData lapdata in Enum.GetValues(typeof(LapData)))
                            {
                                activity.Notes += lapdata.ToString() + " = " + PolarHRM.GetIntTimeData(LapNumber, lapdata).ToString() + Environment.NewLine;
                            }
#endif
                            // Calculate starttime for next lap
                            LapStartTime += actLapDuration;
                        }
#if (DEBUG)
                        Plugin.AddDebugInfo("'Lap Infos' erfolgreich geschrieben.");
#endif
                    }

                }
                #endregion

                if (configInfo.WriteDetailedInfos)
                {
                    PolarHRM.StoreAllData(activity);
#if (DEBUG)
                    activity.Notes += "-- DETAILED REC DATA --------------------------------------------------";
                    foreach (RecData recdata in Enum.GetValues(typeof(RecData)))
                    {
                        activity.Notes += recdata.ToString() + " = " + PolarHRM.GetRecParam(recdata).ToString() + Environment.NewLine;
                    }
                    Plugin.AddDebugInfo("'Detailed Infos' erfolgreich geschrieben.");
#endif
                }
            }
            return true;

        }

        private static void WriteBasicValues( string MonitorName, 
                                              float HRFactor, 
                                              Length.Units distanceUnitRec, 
                                              Length.Units altitudeUnitRec, 
                                              Temperature.Units tempUnitRec, 
                                              IActivity activity,
                                              DeviceConfigurationInfo configInfo)
        {

            activity.AverageHeartRatePerMinuteEntered = PolarHRM.GetRecParam(RecData.REC_AVE_HRATE) * HRFactor;
            activity.MaximumHeartRatePerMinuteEntered = PolarHRM.GetRecParam(RecData.REC_MAX_HRATE) * HRFactor;
            activity.TotalTimeEntered = new TimeSpan(0, 0, PolarHRM.GetRecParam(RecData.REC_REC_LENGTH) / 1000);
#if (DEBUG)
            Plugin.AddDebugInfo("HeartRate und Time erfolgreich geschrieben.");
#endif
            activity.TotalCalories = PolarHRM.GetRecParam(RecData.REC_CALORIES);

            // Fatburning:
            float fatburning = PolarHRM.GetRecParam(RecData.REC_FATCONSUMPTION);
            if (fatburning > 0)
            {
                activity.Notes += String.Format(Properties.Resources.PolarImport_F6_Fatconsumption + Environment.NewLine, fatburning);
            }
#if (DEBUG)
            Plugin.AddDebugInfo("Calories erfolgreich geschrieben.");
#endif
            // Cadencevalues
            activity.AverageCadencePerMinuteEntered = PolarHRM.GetRecParam(RecData.REC_AVG_CAD);
            activity.MaximumCadencePerMinuteEntered = PolarHRM.GetRecParam(RecData.REC_MAX_CAD);
#if (DEBUG)
            Plugin.AddDebugInfo("Cadence erfolgreich geschrieben.");
#endif
            // Now recorded values that may need unit conversion
            // TotalDistance in kilometers / miles
            double totalDistanceRec = PolarHRM.GetRecParam(RecData.REC_TRIP_DIST_STOP) / 10.0f;
            activity.TotalDistanceMetersEntered = (float)Length.Convert(totalDistanceRec, distanceUnitRec, Length.Units.Meter);
#if (DEBUG)
            Plugin.AddDebugInfo(string.Format("Distanz erfolgreich ungewandelt und geschrieben: {0}m", activity.TotalDistanceMetersEntered));
#endif
            
            // Average Speed and Max. Speed, if no timebased values or Lap-values are written:
            if ((configInfo.WriteTimeBasedValues == false) && (configInfo.WriteLapData == false))
            {
                double avgSpeed = PolarHRM.GetRecParam(RecData.REC_AVG_SPEED) / 10.0f;
                //avgSpeed = Length.Convert(avgSpeed, distanceUnitRec, Length.Units.Kilometer);
                double maxSpeed = PolarHRM.GetRecParam(RecData.REC_MAX_SPEED) / 10.0f;
                //maxSpeed = Length.Convert(maxSpeed, distanceUnitRec, Length.Units.Kilometer);
                
                activity.DistanceMetersTrack = new DistanceDataTrack();
                
                activity.DistanceMetersTrack.Add(activity.StartTime , 0f);

                double maxValue = maxSpeed / 3600.0 * 5.0; // Umrechnen in km/s, bzw. miles/s und mit 5s multiplizieren; 
                                                           // ergibt Strecke mit max. Speed und 5 s
                maxValue = Length.Convert(maxValue, distanceUnitRec, Length.Units.Meter); ; // Umrechnen in m
                
                TimeSpan fiveSeconds = new TimeSpan(0, 0, 5);
                DateTime actTime = activity.StartTime + fiveSeconds; 
                activity.DistanceMetersTrack.Add(actTime, (float)maxValue);
                activity.DistanceMetersTrack.Add(activity.StartTime + activity.TotalTimeEntered, activity.TotalDistanceMetersEntered);
            }
            
            // Average temperature in °C / °F
            double avgTempRec = PolarHRM.GetRecParam(RecData.REC_AVE_TEMP) / 10.0f;
            activity.Weather.TemperatureCelsius = (float)Temperature.Convert(avgTempRec, tempUnitRec, Temperature.Units.Celsius);
#if (DEBUG)
            Plugin.AddDebugInfo("Temperaturen erfolgreich umgewandelt und geschrieben.");
#endif
            // Total ascend/descend in meters / foot ( I think ...)
            double totalAscendRec = PolarHRM.GetRecParam(RecData.REC_ASCENT);
            activity.TotalAscendMetersEntered = (float)Length.Convert(totalAscendRec, altitudeUnitRec, Length.Units.Meter);
            double totalDescendRec = PolarHRM.GetRecParam(RecData.REC_DESCENT);
            activity.TotalDescendMetersEntered = (float)Length.Convert(totalDescendRec, altitudeUnitRec, Length.Units.Meter);
#if (DEBUG)
            Plugin.AddDebugInfo("Höhenangeaben erfolgreich umgewandelt und geschrieben.");
#endif
            activity.Notes += Properties.Resources.PolarImport_Import_DirectImportFrom + " " + MonitorName + Environment.NewLine;
            activity.UseEnteredData = true;
#if (DEBUG)
            Plugin.AddDebugInfo("'Basic Values' erfolgreich geschrieben.");
#endif
        }
    }
}
